package cn.huiyunche.driver.service.impl;

import cn.huiyunche.base.service.interfaces.ScPriceconfFreightService;
import cn.huiyunche.base.service.interfaces.ScPriceconfMileService;
import cn.huiyunche.base.service.mappers.DRouteMapper;
import cn.huiyunche.base.service.mappers.ext.DRouteExtMapper;
import cn.huiyunche.base.service.model.DRoute;
import cn.huiyunche.base.service.model.DRouteExample;
import cn.huiyunche.base.service.vo.PageVo;
import cn.huiyunche.driver.service.DRouteService;
import cn.huiyunche.driver.service.dto.DestplaceDto;
import cn.huiyunche.driver.service.dto.StartplaceDto;
import cn.huiyunche.driver.service.form.DRouteForm;
import cn.huiyunche.driver.service.query.DRouteQueryConditions;
import cn.huiyunche.tools.basic.exceptions.BusinessException;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @FileName: cn.huiyunche.driver.service.impl
 * @Description: Description
 * @author: Aaron
 * @date: 2017/2/26 上午11:59
 */
@Service
public class DRouteServiceImpl implements DRouteService {

    private static final Logger LOGGER = LoggerFactory.getLogger(DRouteServiceImpl.class);

    @Autowired
    private DRouteMapper dRouteMapper;

    @Autowired
    private DRouteExtMapper dRouteExtMapper;

    @Autowired
    private ScPriceconfMileService scPriceconfMileService;

    @Autowired
    private ScPriceconfFreightService scPriceconfFreightService;

    @Override
    public Integer add(DRouteForm form, BindingResult br) {
        LOGGER.info("DRouteServiceImpl.add params : {}", form);

        if (null == form) {
            LOGGER.error("DRouteServiceImpl.add param form must not be null");
            throw new IllegalArgumentException("线路表单不能为空");
        }

        //验证表单
        verificationForm(br);

        /**
         * 判断线路是否唯一（起始市和目的地市）
         */
        List<DRoute> routes = this.verificationOTagAndDTagAndNameUnique(form.getOTag(), form.getDTag(), form.getName());
        if (CollectionUtils.isNotEmpty(routes)) {

            DRoute route = routes.get(0);

            if (routes != null && form.getName().equals(route.getName())) {
                LOGGER.error("DRouteServiceImpl.add error routes is not empty ");
                throw new BusinessException("线路名称已存在！");
            }
            LOGGER.error("DRouteServiceImpl.add error routes is not empty ");
            throw new BusinessException("线路已存在！");
        }

        DRoute route = new DRoute();
        BeanUtils.copyProperties(form, route);
        route.setEnable(true);

        dRouteMapper.insertSelective(route);

        return route.getId();
    }

    @Override
    public DRoute selectByPrimaryKey(Integer id) {
        LOGGER.info("DRouteServiceImpl.selectByPrimaryKey param : {}", id);

        if (null == id) {
            LOGGER.error("DRouteServiceImpl.selectByPrimaryKey param id must not be null");
            throw new IllegalArgumentException("主键不能为空");
        }

        return dRouteMapper.selectByPrimaryKey(id);
    }

    private void verificationForm(BindingResult br) {

        if (null == br) {
            LOGGER.error("DRouteServiceImpl.verificationForm error br is null");
            throw new IllegalArgumentException("BindingResult is null");
        }

        if (br.hasErrors()) {
            List<ObjectError> list = br.getAllErrors();
            LOGGER.error("DRouteServiceImpl.add error : {}", list.get(0).getDefaultMessage());
            throw new IllegalArgumentException(list.get(0).getDefaultMessage());
        }
    }

    public Integer update(DRouteForm form, BindingResult br) {
        LOGGER.info("DRouteServiceImpl.update params : {}", form);

        if (null == form) {
            LOGGER.error("DRouteServiceImpl.update param form must not be null");
            throw new IllegalArgumentException("线路表单不能为空");
        }

        //验证表单
        verificationForm(br);


        /**
         * 判断线路是否唯一（起始市和目的地市）
         */
        List<DRoute> routes = this.verificationOTagAndDTagAndNameUnique(form.getOTag(), form.getDTag(), form.getName());
        if (CollectionUtils.isNotEmpty(routes)) {
            if (routes.size() > 1) {
                LOGGER.error("DRouteServiceImpl.add error routes is not empty ");
                throw new BusinessException("线路已存在！");
            } else {
                if (null != form.getId() && form.getId() != routes.get(0).getId()) {
                    LOGGER.error("DRouteServiceImpl.add error routes is not empty ");
                    throw new BusinessException("线路已存在！");
                }
            }
        }

        DRoute route = new DRoute();
        BeanUtils.copyProperties(form, route);

        dRouteMapper.updateByPrimaryKeySelective(route);

        return route.getId();
    }

    @Override
    public Integer enableOrDisabled(Integer id, boolean enableOrDisabled) {
        LOGGER.info("DRouteServiceImpl.enableOrDisabled params : {}, {}", id, enableOrDisabled);

        DRoute route = new DRoute();
        route.setId(id);
        route.setEnable(enableOrDisabled);

        dRouteMapper.updateByPrimaryKeySelective(route);

        return null;
    }

    @Override
    public Map<String, Object> selectListByConditions(PageVo pageVo, DRouteQueryConditions conditions) {
        LOGGER.info("DRouteServiceImpl.selectListByConditions params : {}, {}", pageVo, conditions);

//        if( null == pageVo ){
//            LOGGER.error("DRouteServiceImpl.selectListByConditions param pageVo must not be null");
//            throw new IllegalArgumentException("分页信息不能为空");
//        }
        if (null == conditions) {
            LOGGER.error("DRouteServiceImpl.selectListByConditions param must conditions not be null ");
            throw new IllegalArgumentException("查询条件信息不能为空");
        }

        Map<String, Object> map = new HashMap<>();

        String orderByClause = null;
        if (null != pageVo) {
            orderByClause = StringUtils.isNotBlank(pageVo.getOrder()) == true ? pageVo.getOrder() : " update_time DESC";
        }


        DRouteExample example = new DRouteExample();
        DRouteExample.Criteria criteria = example.createCriteria();

        if (StringUtils.isNotBlank(conditions.getName())) {
            criteria.andNameLikeInsensitive("%" + conditions.getName() + "%");
        }
        if (StringUtils.isNotBlank(conditions.getOTag())) {
            criteria.andOTagLikeInsensitive("%" + conditions.getOTag() + "%");
        }
        if (StringUtils.isNotBlank(conditions.getOProvince())) {
            criteria.andOProvinceEqualTo(conditions.getOProvince());
        }
        if (StringUtils.isNotBlank(conditions.getOCity())) {
            criteria.andOCityEqualTo(conditions.getOCity());
        }
        if (StringUtils.isNotBlank(conditions.getOCounty())) {
            criteria.andOCountyEqualTo(conditions.getOCounty());
        }
        if (StringUtils.isNotBlank(conditions.getDTag())) {
            criteria.andDTagLikeInsensitive("%" + conditions.getDTag() + "%");
        }
        if (StringUtils.isNotBlank(conditions.getDProvince())) {
            criteria.andDProvinceEqualTo(conditions.getDProvince());
        }
        if (StringUtils.isNotBlank(conditions.getDCity())) {
            criteria.andDCityEqualTo(conditions.getDCity());
        }
        if (StringUtils.isNotBlank(conditions.getDCounty())) {
            criteria.andDCountyEqualTo(conditions.getDCounty());
        }
        if (StringUtils.isNotBlank(conditions.getOProvinceCode())) {
            criteria.andOProvinceCodeEqualTo(conditions.getOProvinceCode());
        }
        if (StringUtils.isNotBlank(conditions.getOCityCode())) {
            criteria.andOCityCodeEqualTo(conditions.getOCityCode());
        }
        if (StringUtils.isNotBlank(conditions.getOCountyCode())) {
            criteria.andOCountyCodeEqualTo(conditions.getOCountyCode());
        }
        if (StringUtils.isNotBlank(conditions.getDProvinceCode())) {
            criteria.andDProvinceCodeEqualTo(conditions.getDProvinceCode());
        }
        if (StringUtils.isNotBlank(conditions.getDCityCode())) {
            criteria.andDCityCodeEqualTo(conditions.getDCityCode());
        }
        if (StringUtils.isNotBlank(conditions.getDCountyCode())) {
            criteria.andDCountyCodeEqualTo(conditions.getDCountyCode());
        }
        if (conditions.getEnable() != null) {
            criteria.andEnableEqualTo(conditions.getEnable());
        }

        if (null != pageVo) {
            pageVo.setTotalRecord(dRouteMapper.countByExample(example));
            example.setLimitStart(pageVo.getStartIndex());
            example.setLimitEnd(pageVo.getPageSize());
            example.setOrderByClause(orderByClause);
        }

        List<DRoute> list = dRouteMapper.selectByExample(example);
        map.put("list", list);

        if (null != pageVo) {
            map.put("page", pageVo);
        }

        return map;
    }

    @Override
    public List<DRoute> verificationOTagAndDTagAndNameUnique(String oTag, String dTag, String routeName) {
        LOGGER.info("DRouteServiceImpl.selectByOCityCodeAndDCityCode params : {}, {}", oTag, dTag);

        if (StringUtils.isBlank(oTag)) {
            LOGGER.error("DRouteServiceImpl.selectByOCityCodeAndDCityCodeAndName param oTag must not be null");
            throw new IllegalArgumentException("起始地市不能为空");
        }
        if (StringUtils.isBlank(dTag)) {
            LOGGER.error("DRouteServiceImpl.selectByOCityCodeAndDCityCodeAndName param dTag must not be null");
            throw new IllegalArgumentException("目的地市不能为空");
        }
        if (StringUtils.isBlank(routeName)) {
            LOGGER.error("DRouteServiceImpl.selectByOCityCodeAndDCityCodeAndName param routeName must not be null");
            throw new IllegalArgumentException("线路名称不能为空");
        }

        DRouteExample example = new DRouteExample();
        example.createCriteria().andOTagEqualTo(oTag).andDTagEqualTo(dTag);

        List<DRoute> list = dRouteMapper.selectByExample(example);

        if (CollectionUtils.isEmpty(list)) {
            DRouteExample example1 = new DRouteExample();
            example1.createCriteria().andNameEqualTo(routeName);

            list = dRouteMapper.selectByExample(example1);
        }

        return list;
    }

    @Override
    public void del(Integer id) throws Exception {
        LOGGER.info("DRouteServiceImpl.del param : {}", id);

        if ( null == id || 0 == id.intValue() ) {
            LOGGER.error("DRouteServiceImpl.del param id must not be null");
            throw new IllegalArgumentException("主键不能为空");
        }

        /**
         * 验证是否更里程变更有关联
         */
        if ( CollectionUtils.isNotEmpty(scPriceconfMileService.selectByRouteId(id)) ) {
            LOGGER.error("DRouteServiceImpl.del associated with mile");
            throw new BusinessException("请先移除线路里程变更的关联");
        }

        /**
         * 验证是否更价格变更有关联
         */
        if ( CollectionUtils.isNotEmpty(scPriceconfFreightService.selectByRouteId(id)) ) {
            LOGGER.error("DRouteServiceImpl.del associated with freight");
            throw new BusinessException("请先移除线路价格变更的关联");
        }


        dRouteMapper.deleteByPrimaryKey(id);
    }

    @Override
    public List<DestplaceDto> findByDestTag(String dTag) {
        List<DRoute> dRouteList = dRouteExtMapper.findByDestTag(dTag, 0, 10);
        List<DestplaceDto> destList = new ArrayList<DestplaceDto>();
        for (DRoute dRoute : dRouteList) {
            DestplaceDto destplaceDto = new DestplaceDto();
            destplaceDto.setName(dRoute.getdProvince() + " " + dRoute.getdTag());
            destList.add(destplaceDto);
        }
        return destList;
    }

    @Override
    public List<StartplaceDto> findByStartTag(String oTag) {
        List<DRoute> dRouteList = dRouteExtMapper.findByStartTag(oTag, 0, 10);
        List<StartplaceDto> startList = new ArrayList<StartplaceDto>();
        for (DRoute dRoute : dRouteList) {
            StartplaceDto startplaceDto = new StartplaceDto();
            startplaceDto.setName(dRoute.getoProvince() + " " + dRoute.getoTag());
            startList.add(startplaceDto);
        }
        return startList;
    }
}
